import "babel-polyfill";
import {map, zip} from "../../../algorithm/iterator";
import Integer from "../../number/integer";
import Fraction from "../../number/fraction";
import PolynomialZ from "../polynomial-Z";
import PolynomialQ from "../polynomial-Q";

var compare = function(p, q) {
    if (this === PolynomialZ) {
        var compareNumber = Integer.compare;
    } else if (this === PolynomialQ) {
        var compareNumber = Fraction.compare;
    } else {
        var compareNumber = Integer.compare;
        let prime = this.modulus;
        let half_prime = Integer.shr(prime, 1);
        let transform = n => Integer.compare(n, half_prime) <= 0 ? n : Integer.subtract(n, prime);
        p = new PolynomialZ(...p::map(transform));
        q = new PolynomialZ(...q::map(transform));
    }

    if (p.degree !== q.degree) {
        return p.degree - q.degree;
    } else {
        for (let [m, n] of zip(p[Symbol.iterator](-1), q[Symbol.iterator](-1))) {
            let comparison = compareNumber(m, n);
            if (comparison !== 0) {
                return comparison;
            }
        }
        return 0;
    }
};

export var prettyPrint = function(symbol = "x") {
    var factor_result = [...this];
    if (factor_result.length === 0) {
        return "1";
    } else if (factor_result.length === 1) {
        let [polynomial, degree] = factor_result[0];
        polynomial = polynomial.toString(symbol);
        if (degree === 1) {
            return polynomial;
        } else if (polynomial.includes(" ")) {
            return `(${polynomial})^${degree}`;
        } else {
            return `${polynomial}^${degree}`
        }
    }
    var PolynomialType = factor_result[0][0].constructor;
    return factor_result.sort((p, q) => PolynomialType::compare(p[0], q[0])).map(function([polynomial, degree]) {
        polynomial = polynomial.toString(symbol);
        if (polynomial.includes(" ")) {
            polynomial = `(${polynomial})`;
        }
        if (degree === 1) {
            return polynomial;
        } else {
            return `${polynomial}^${degree}`
        }
    }).join(" * ");
};
